package ru.ifmo.swing.genetics.termination;

import org.uncommons.watchmaker.framework.PopulationData;
import org.uncommons.watchmaker.framework.TerminationCondition;
import ru.ifmo.swing.EvolutionControlWithConfigProvider;
import ru.ifmo.swing.Panel;

import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author avhaliullin
 */
public class FitnessValueCondition implements EvolutionControlWithConfigProvider, TerminationCondition {
    private final Panel control = new Panel();
    private final SpinnerModel spinnerModel;
    private final double defaultValue;

    public FitnessValueCondition(double defaultValue, double step) {
        this.defaultValue = defaultValue;
        spinnerModel = new SpinnerNumberModel(this.defaultValue, 1d, null, step);
        JSpinner spinner = new JSpinner(spinnerModel);
        spinner.setMaximumSize(new Dimension(150, 20));
        control.add(spinner);
    }

    public JComponent getControl() {
        return control;
    }

    public void reset() {
        spinnerModel.setValue(defaultValue);
    }

    public void setDescription(String description) {
        control.setTitle(description);
    }

    public boolean shouldTerminate(PopulationData<?> populationData) {
        return populationData.isNaturalFitness() ?
                ((Number) spinnerModel.getValue()).doubleValue() <= populationData.getBestCandidateFitness() :
                ((Number) spinnerModel.getValue()).doubleValue() >= populationData.getBestCandidateFitness();
    }

    public Map<String, Object> getParamValues() {
        Map<String, Object> res = new HashMap<String, Object>();
        res.put("Fitness", spinnerModel.getValue());
        return res;
    }
}
